package com.jinzhi.jzweb.service.moduleConfig.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.jzweb.dao.moduleConfig.SignGgradeMapper;
import com.jinzhi.jzweb.domain.StuSignUpComDO;
import com.jinzhi.jzweb.pojo.ModuleConfig.*;
import com.jinzhi.jzweb.service.StuSignUpComService;
import com.jinzhi.jzweb.service.moduleConfig.SignGradeService;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/*
 *  @author : JingChangTian
 *  @date   : 2023/11/30 14:44
 *  @description :
 *
 */
@Service
public class SignGradeServiceImpl extends ServiceImpl<SignGgradeMapper, SignGrade> implements SignGradeService {

    /**
     * 考生
     */
    private final StuSignUpComService sign;

    public SignGradeServiceImpl(StuSignUpComService Sign) {
        this.sign = Sign;
    }

    @Override
    public Result insertOrUpdateBatchs(List<SignGrade> signGrades) {
        if(signGrades.isEmpty()){
            return Result.fail("数据为null");
        };
        return this.insertOrUpdateBatch(signGrades)  ? Result.ok() : Result.fail();
    }

    @Override
    public Result getSignGrades(SignGrade signGrade) {
        SignGradeStuSignComVO  signComVO = new SignGradeStuSignComVO();
        //根据批次查询已解密考生信息
        Page<StuSignUpComDO> page = new Page<StuSignUpComDO>(signGrade.getCurrent(),signGrade.getSize());
        EntityWrapper wrapper = new EntityWrapper<StuSignUpComDO>();
                wrapper.eq(Objects.nonNull(signGrade.getCbatchId()),"cbatch_id",signGrade.getCbatchId()).
                eq("decrypt",1);
        if(signGrade.getCompetition().equals("B1")||signGrade.getCompetition().equals("B2")){
            wrapper.isNotNull("reality_um2");
        }
        if(signGrade.getCompetition().equals("B3")||signGrade.getCompetition().equals("B4")){
            wrapper.isNotNull("reality_um4");
        }
        List<StuSignUpComDO> signs = sign.selectList(wrapper);
        if(signs.isEmpty()){
            return Result.ok(signComVO);
        }
        //根据批次查询考生成绩
        List<SignGrade> signGrades = this.selectList(new EntityWrapper<SignGrade>().
                eq(Objects.nonNull(signGrade.getCbatchId()),"cbatch_id",signGrade.getCbatchId()).
                eq(StringUtil.notEmpty(signGrade.getCompetition()),"competition",signGrade.getCompetition()));
        if(signGrades.isEmpty()){
            page.setRecords(signs);
            signComVO.setSignUpComDOPage(page);
            return Result.ok(signComVO);
        }
        signs.forEach(a -> {
            List<SignGrade> list = signGrades.stream().filter(b -> b.getSignId().equals(a.getId())).collect(Collectors.toList());
            //获取序号裁判分数
            DoubleSummaryStatistics collect1 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==1).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect2 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==2).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect3 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==3).collect(Collectors.summarizingDouble(SignGrade::getMark));
            //实例赋值
            a.setSignGradeDTO(new SignGradeDTO());
            a.getSignGradeDTO().setSignGrades(list);
            a.getSignGradeDTO().setMarkOne(collect1.getAverage());
            a.getSignGradeDTO().setMarkTwO(collect2.getAverage());
            a.getSignGradeDTO().setMarkThree(collect3.getAverage());
            //计算平均分
            DoubleSummaryStatistics markTotal = (DoubleSummaryStatistics) list.stream().collect(Collectors.summarizingDouble(SignGrade::getMark));
            a.setMarkTotal(markTotal.getAverage());
        });
        page.setRecords(signs);
        //获取考试人数、最高分、最低分
        DoubleSummaryStatistics collect = (DoubleSummaryStatistics) signs.stream().collect(Collectors.summarizingDouble(StuSignUpComDO::getMarkTotal));
        signComVO.setSignUpComDOPage(page);
        signComVO.setHighestScore(collect.getMax());
        signComVO.setLowestMark(collect.getMin());
        signComVO.setCompetitionNumber(Integer.parseInt(String.valueOf(collect.getCount())));
        return Result.ok(signComVO);
    }

    @Override
    public Result getStuSignGrades(SignGrade signGrade) {
        //根据批次，查询考生信息
        Page<StuSignUpComDO> page = new Page<StuSignUpComDO>(signGrade.getCurrent(),signGrade.getSize());
        EntityWrapper wrapper = new EntityWrapper<StuSignUpComDO>();
        wrapper.eq(Objects.nonNull(signGrade.getCbatchId()),"cbatch_id",signGrade.getCbatchId());
        if(signGrade.getCompetition().equals("B1")||signGrade.getCompetition().equals("B2")){
            wrapper.isNotNull("reality_um2");
        }
        if(signGrade.getCompetition().equals("B3")||signGrade.getCompetition().equals("B4")){
            wrapper.isNotNull("reality_um4");
        }
        List<StuSignUpComDO> signs = sign.selectList(wrapper);
        if(signs.isEmpty()){
            page.setRecords(signs);
            return Result.ok(page);
        }
        //根据批次，场次查询成绩
        List<SignGrade> signGrades = this.selectList(new EntityWrapper<SignGrade>().
                eq(Objects.nonNull(signGrade.getCbatchId()),"cbatch_id",signGrade.getCbatchId()).
                eq(StringUtil.notEmpty(signGrade.getCompetition()),"competition",signGrade.getCompetition()));
        if(signGrades.isEmpty()){
            page.setRecords(signs);
            return Result.ok(page);
        }
        signs.forEach(a -> {
            List<SignGrade> list = signGrades.stream().filter(b -> b.getSignId().equals(a.getId())).collect(Collectors.toList());
            DoubleSummaryStatistics collect1 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==1).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect2 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==2).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect3 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==3).collect(Collectors.summarizingDouble(SignGrade::getMark));
            a.setSignGradeDTO(new SignGradeDTO());
            a.getSignGradeDTO().setSignGrades(list);
            a.getSignGradeDTO().setMarkOne(collect1.getAverage());
            a.getSignGradeDTO().setMarkTwO(collect2.getAverage());
            a.getSignGradeDTO().setMarkThree(collect3.getAverage());
        });
        //根据二次加密排序
        if(signGrade.getCompetition().equals("B1")||signGrade.getCompetition().equals("B2")){
            signs = signs.stream().sorted(Comparator.comparing(StuSignUpComDO::getRealityNm2, Comparator.reverseOrder())).collect(Collectors.toList());
        }
        if(signGrade.getCompetition().equals("B3")||signGrade.getCompetition().equals("B4")){
            signs = signs.stream().sorted(Comparator.comparing(StuSignUpComDO::getRealityNm4, Comparator.reverseOrder())).collect(Collectors.toList());
        }
        signs = signs.stream().sorted(Comparator.comparing(StuSignUpComDO::getMarkTotal, Comparator.nullsFirst(Double::compareTo))).collect(Collectors.toList());
        page.setRecords(signs);
        return Result.ok(page);
    }

    @Override
    public Result stuSignGradederive(HttpServletResponse response,Long cbatchId,String competition) throws Exception{
        List<SignGradeExB1Vo>  exB1Vos = new ArrayList<>();
        //根据批次查询已解密考生信息
        List<StuSignUpComDO> signs = sign.selectList(new EntityWrapper<StuSignUpComDO>().
                eq(Objects.nonNull(cbatchId),"cbatch_id",cbatchId).
                eq("decrypt",1).isNotNull("reality_um2").isNotNull("reality_um2"));
        if(signs.isEmpty()){
            return Result.fail("暂无考生信息");
        }
        //根据批次查询考生成绩
        List<SignGrade> signGrades = this.selectList(new EntityWrapper<SignGrade>().
                eq(Objects.nonNull(cbatchId),"cbatch_id",cbatchId).
                eq(StringUtil.notEmpty(competition),"competition",competition));
        if(signGrades.isEmpty()){
            return Result.fail("暂无考试成绩");
        }
        signs.forEach(a -> {
            SignGradeExB1Vo b1Vo = new SignGradeExB1Vo();
            List<SignGrade> list = signGrades.stream().filter(b -> b.getSignId().equals(a.getId())).collect(Collectors.toList());
            DoubleSummaryStatistics collect1 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==1).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect2 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==2).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect3 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==3).collect(Collectors.summarizingDouble(SignGrade::getMark));
            b1Vo.setScore1(collect1.getAverage());
            b1Vo.setScore2(collect2.getAverage());
            b1Vo.setScore3(collect3.getAverage());
            try {
                //通过反射获取相同属性值
                copyProperties(a, b1Vo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            DoubleSummaryStatistics markTotal = (DoubleSummaryStatistics) list.stream().collect(Collectors.summarizingDouble(SignGrade::getMark));
            b1Vo.setMarkTotal(markTotal.getAverage());
            if(competition.equals("B3")||competition.equals("B4")){
                b1Vo.setRealityNm1(a.getRealityNm3());
                b1Vo.setRealityNm2(a.getRealityNm4());
            }
            exB1Vos.add(b1Vo);
        });
        //导出操作
        EasyPoiUtil.exportExcel(exB1Vos, "B赛场成绩导出", "B赛场成绩导出", SignGradeExB1Vo.class, "B赛场成绩导出", response);
        return Result.ok();
    }

    @Override
    public Result recordderive(HttpServletResponse response, Long cbatchId, String competition) throws Exception {
        List<RecordExVo> recordExVos = new ArrayList<>();
        EntityWrapper wrapper = new EntityWrapper<StuSignUpComDO>();
        wrapper.eq(Objects.nonNull(cbatchId),"cbatch_id",cbatchId);
        if(competition.equals("B1")||competition.equals("B2")){
            wrapper.isNotNull("reality_um2");
        }
        if(competition.equals("B3")||competition.equals("B4")){
            wrapper.isNotNull("reality_um4");
        }
        List<StuSignUpComDO> signs = sign.selectList(wrapper);
        if(signs.isEmpty()){
            return Result.fail("暂无考生信息");
        }
        //根据批次查询考生成绩
        List<SignGrade> signGrades = this.selectList(new EntityWrapper<SignGrade>().
                eq(Objects.nonNull(cbatchId),"cbatch_id",cbatchId).
                eq(StringUtil.notEmpty(competition),"competition",competition));
        if(signGrades.isEmpty()){
            return Result.fail("暂无考试成绩");
        }
        signs.forEach(a -> {
            RecordExVo recordExVo = new RecordExVo();
            List<SignGrade> list = signGrades.stream().filter(b -> b.getSignId().equals(a.getId())).collect(Collectors.toList());
            DoubleSummaryStatistics collect1 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==1).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect2 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==2).collect(Collectors.summarizingDouble(SignGrade::getMark));
            DoubleSummaryStatistics collect3 = (DoubleSummaryStatistics) list.stream().filter(c -> c.getNumberReferee()==3).collect(Collectors.summarizingDouble(SignGrade::getMark));
            recordExVo.setScore1(collect1.getAverage());
            recordExVo.setScore2(collect2.getAverage());
            recordExVo.setScore3(collect3.getAverage());
            if(competition.equals("B1")||competition.equals("B2")){
                recordExVo.setRealityNm2(a.getRealityNm2());
            }
            if(competition.equals("B3")||competition.equals("B4")){
                recordExVo.setRealityNm2(a.getRealityNm4());
            }
            recordExVos.add(recordExVo);
        });

        //导出操作
        EasyPoiUtil.exportExcel(recordExVos, "B赛场录分导出", "B赛场录分导出", RecordExVo.class, "B赛场录分导出", response);
        return Result.ok();
    }


    /**
     * 反射赋值
     * @param source
     * @param target
     * @param <T>
     * @param <S>
     * @return
     * @throws Exception
     */
    public static <T, S> T copyProperties(S source, T target) throws Exception {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();

        Field[] sourceFields = sourceClass.getDeclaredFields();
        for (Field sourceField : sourceFields) {
            String fieldName = sourceField.getName();
            Field targetField = null;
            try {
                targetField = targetClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                // 目标对象不存在该属性，忽略
                continue;
            }

            sourceField.setAccessible(true);
            targetField.setAccessible(true);

            Object value = sourceField.get(source);
            targetField.set(target, value);
        }
        return target;
    }

}
